package com.cn.admin.service.impl;

import com.cn.admin.dao.MenuMapper;
import com.cn.admin.dao.MenuRoleMapper;
import com.cn.admin.entity.Menu;
import com.cn.admin.entity.MenuQuery;
import com.cn.admin.entity.MenuRole;
import com.cn.admin.entity.MenuRoleQuery;
import com.cn.admin.node.MenuNode;
import com.cn.admin.node.Node;
import com.cn.admin.node.ZTreeNode;
import com.cn.admin.service.MenuRoleService;
import com.cn.admin.utils.BaseServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class MenuRoleServiceImpl extends BaseServiceImpl<MenuRole, MenuRoleQuery,Long> implements MenuRoleService {

    private static Logger logger = LoggerFactory.getLogger(MenuRoleServiceImpl.class);


    @Autowired
    MenuRoleMapper menuRoleMapper;

    @Autowired
    MenuMapper menuMapper;

    @Override
    public List<MenuNode> getMenusByRoleIds(List roleList) {
        return menuRoleMapper.getMenusByRoleIds(roleList);
    }

    @Override
    public List<MenuNode> getMenusTreeByRoleIds(List<Long> roleList) {
        List<MenuNode> menus = menuRoleMapper.getMenusByRoleIds(roleList);
        List<MenuNode> result =  generateTree(menus);
        for(MenuNode menuNode:result){
            if(!menuNode.getChildren().isEmpty()){
                sortTree(menuNode.getChildren());
                for(MenuNode menuNode1: menuNode.getChildren()){
                    if(!menuNode1.getChildren().isEmpty()) {
                        sortTree(menuNode1.getChildren());
                    }
                }
            }
        }
        sortTree(result);
        return result;
    }


    private void sortTree(List<MenuNode> list){
        Collections.sort(list, new Comparator<MenuNode>() {
            @Override
            public int compare(MenuNode o1, MenuNode o2) {
                return o1.getNum()-o2.getNum();
            }
        });
    }
    private List<MenuNode> generateTree(List<MenuNode> list){
        List<MenuNode> result = new ArrayList<>(20);
        //Map<Long,MenuNode> map = Lists.toMap(list,"id");
        Map<Long,MenuNode> map=this.toMap(list);
        for(Map.Entry<Long,MenuNode> entry:map.entrySet()){
            MenuNode menuNode = entry.getValue();

            if(menuNode.getParentId().intValue()!=0){
                MenuNode parentNode = map.get(menuNode.getParentId());
                if(null !=parentNode){
                    parentNode.getChildren().add(menuNode);
                }
            }else{
                result.add(menuNode);
            }
        }
        return result;

    }

    private Map<Long, MenuNode> toMap(List<MenuNode> list) {

        Map map=new HashMap();
        for (MenuNode menuNode:list) {
            Long id = menuNode.getId();
            map.put("id",menuNode);
        }
        return  map;
    }

    public List<ZTreeNode> menuTreeList() {
        List list = menuMapper.menuTreeList();
        List<ZTreeNode> nodes  =new ArrayList<>();
        for(int i=0;i<list.size();i++){
            Object[] source = (Object[]) list.get(i);
            ZTreeNode node = new ZTreeNode();
            node.setId(Long.valueOf(source[0].toString()));
            node.setpId(Long.valueOf(source[1].toString()));
            node.setName(source[2].toString());
            node.setIsOpen(Boolean.valueOf(source[3].toString()));
            nodes.add(node);
        }
        return nodes;
    }

    public List<ZTreeNode> menuTreeListByMenuIds(List<Long> menuIds) {
        List list = menuMapper.menuTreeListByMenuIds(menuIds);
        List<ZTreeNode> nodes  =new ArrayList<>();
        for(int i=0;i<list.size();i++){
            Object[] source = (Object[]) list.get(i);
            ZTreeNode node = new ZTreeNode();
            node.setId(Long.valueOf(source[0].toString()));
            node.setpId(Long.valueOf(source[1].toString()));
            node.setName(source[2].toString());
            node.setIsOpen(Boolean.valueOf(source[3].toString()));
            node.setChecked(Boolean.valueOf(source[4].toString()));
            nodes.add(node);
        }
        return nodes;
    }

    public void menuSetPcode(Menu menu) {
        if (StringUtils.isEmpty(menu.getPcode()) || menu.getPcode().equals("0")) {
            menu.setPcode("0");
            menu.setPcodes("[0],");
            menu.setLevels(1);
        } else {

            MenuQuery menuQuery=new MenuQuery();
            menuQuery.createCriteria().andPcodeEqualTo(menu.getPcode());
            Menu pMenu = menuMapper.selectOneByExample(menuQuery);
            Integer pLevels = pMenu.getLevels();
            menu.setPcode(pMenu.getCode());

            //如果编号和父编号一致会导致无限递归
            if (menu.getCode().equals(menu.getPcode())) {
                throw new RuntimeException();
            }

            menu.setLevels(pLevels + 1);
            menu.setPcodes(pMenu.getPcodes() + "[" + pMenu.getCode() + "],");
        }
    }

    public List<Node> generateMenuTreeForRole(List<ZTreeNode> list){

        List<Node> nodes = new ArrayList<>(20);
        for(ZTreeNode menu:list){
            Node permissionNode = new Node();
            permissionNode.setId(menu.getId());
            permissionNode.setName(menu.getName());
            permissionNode.setPid(menu.getpId());
            permissionNode.setChecked(menu.getChecked());
            nodes.add(permissionNode);
        }
        for(Node permissionNode:nodes){
            for(Node child:nodes){
                if(child.getPid().intValue() == permissionNode.getId().intValue()){
                    permissionNode.getChildren().add(child);
                }
            }
        }
        List<Node> result = new ArrayList<>(20);
        for(Node node:nodes){
            if(node.getPid().intValue() == 0){
                result.add(node);
            }
        }
        return result;


    }
}
